package com.googlecode.cswish.struts.interceptor;

import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.googlecode.cswish.Config;
import com.googlecode.cswish.model.PageElements;
import com.googlecode.cswish.struts.Invoker;
import com.googlecode.cswish.struts.Routing;
import com.googlecode.cswish.struts.conversion.PageConverter;
import com.googlecode.cswish.struts.conversion.PageElementService;
import com.googlecode.cswish.struts.spring.BeanIntrospector;
import com.googlecode.cswish.struts.spring.GenericJPAService;
import com.googlecode.cswish.util.FrameConstant;
import com.googlecode.cswish.util.Functions;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.util.ValueStack;

/**
 * Generate a page structure according to action information
 * 
 * @author Jerry.Feng Date: 2008-5-15
 */
public class PageElementInterceptor extends AbstractInterceptor {

	private static final Log logger = LogFactory.getLog(PageElementInterceptor.class);
	
	@Resource
	private PageConverter pageConverter;
	
	@Resource
    private Routing routing;
    
    @Resource
    private Functions functions;
    
    @Resource
    private BeanIntrospector beanIntrospector;
    
    @Resource
    private PageElementService pageElementService;
    
    @Resource
    private Config config;
	
	public String intercept(ActionInvocation invocation) throws Exception {
    	String name = invocation.getProxy().getActionName();
    	Invoker invoker = routing.path2Invoker(name, true);
    	ValueStack stack = invocation.getStack();
    	Map<String, Object> context = stack.getContext();
    	context.put(FrameConstant.STACK_ACTIONNAME, invoker.actionName);
    	context.put(FrameConstant.STACK_FUNCTION, functions);
    	
    	String method = invoker.methodName;
    	// for the generic page, they use their own PageElements 
    	Object resultCode = invocation.getInvocationContext().getParameters().get(FrameConstant.PARAM_RESULTCODE);
    	String strResultCode = null;
    	if (resultCode != null && resultCode instanceof String[]) {
			String[] resultCodes = (String[]) resultCode;
			// NOTICE: '$element' share the original PageElements
			if (resultCodes.length > 0 && !resultCodes[0].equals(FrameConstant.PARAM_RESULT_ELEMENT)) {
				strResultCode = resultCodes[0];
			}
    	}
    	
    	String simpleModelName = beanIntrospector.getSimpleName(invoker.actionName);
    	PageElements ps = new PageElements();
    	pageConverter.convertPageByClass(simpleModelName, method, ps);
    	// TODO: reuse the ps?
    	// input method and submit method share the same pageElemetns 
    	//if not , null value update defect
    	
    	PageElements userElements = pageElementService.getPageElements(invocation, simpleModelName, method, strResultCode, true);
    	//TODO: better solutions? and others pageElementService.getKey should refactor.
    	if (userElements != null && userElements.getAllElements().size() == 0){
    		if (!method.startsWith("_")){
    			method = "_" + method;
    			userElements = pageElementService.getPageElements(invocation, simpleModelName, method, strResultCode, true);
    		}
    	}
    	//end
    	
    	if (userElements == null) {
    		logger.error("Can't find the PageElements, page parser issue?");
    		userElements = new PageElements();
    	} else {
	    	if (userElements.getContext() != null) {
	    		userElements.getContext().beginRequest();
	    	}
    	}
    	context.put(FrameConstant.STACK_PAGEELEMENTS, userElements);
    	return invocation.invoke();
	}
}